import React, { PropsWithChildren, useRef, useState } from 'react';

import MenuIcon from '@/assets/images/shared/icon-menu.svg';
import { Avatar } from '@/entities/profile';
import { innerUrls } from '@/shared/constants';
import LogoXL from '@/shared/icons/logo/companyNameFullXL.svg';
import { ProfileTabVariants } from '@/shared/interfaces';
import { Button } from '@/shared/ui';
import cn from 'classnames';
import Image from 'next/image';
import { useIsomorphicLayoutEffect, useOnClickOutside } from 'usehooks-ts';

import cs from './Header.module.scss';
import { Nav } from './Nav';

export interface ProfileModalItem {
  Logo: React.ReactNode;
  Component: React.ReactNode;
  onClick?: () => void;
  id: ProfileTabVariants | 'logout';
  title?: string;
}
function createThrottledCallback(cb: () => void, timeout = 100) {
  let wait = false;
  return () => {
    if (wait) {
      return;
    }

    wait = true;
    setTimeout(() => {
      cb();
      wait = false;
    }, timeout);
  };
}

function getScrollPosition(element: Element | (Window & typeof globalThis)): number {
  if (element instanceof Window) {
    return element.scrollY;
  }

  return element.scrollTop;
}

type HeaderProps = {
  className?: string;
  scrollingElementSelector?: string;
} & PropsWithChildren;

export const Header = ({ children, className, scrollingElementSelector: scrollingElementClass }: HeaderProps) => {
  const [showNav, setShowNav] = useState(false);
  const [showBorder, setShowBorder] = useState(false);
  const hideNav = () => setShowNav(false);

  useIsomorphicLayoutEffect(() => {
    const container = scrollingElementClass ? document.getElementById(scrollingElementClass) : window;
    if (!container) {
      return;
    }
    let prevScroll = getScrollPosition(container) > 0;
    const throttledOnScroll = createThrottledCallback(() => {
      const newScroll = getScrollPosition(container) > 0;
      if (newScroll !== prevScroll) {
        setShowBorder(newScroll);
        prevScroll = newScroll;
      }
    });
    container.addEventListener('scroll', throttledOnScroll);
    container.addEventListener('mouseclick', hideNav);

    return () => {
      container.removeEventListener('scroll', throttledOnScroll);
      container.removeEventListener('mouseclick', hideNav);
    };
  }, []);

  const ref = useRef(null);
  useOnClickOutside(ref, hideNav);

  return (
    <>
      <header className={cn('header', cs.wrapper, className, { [cs.windowScrolled]: showBorder })}>
        <div className={cs.content}>
          <div className={cs.burger_container} ref={ref}>
            <Button
              aria-label="Навигация"
              className={cs.burger}
              data-testid="button-toggle-nav"
              onClick={() => setShowNav((prev) => !prev)}
              type="button"
            >
              <Image alt="navigation burger" height={24} priority src={MenuIcon} width={24} />
            </Button>
            {showNav && <Nav closeSelf={hideNav} isMobile onMouseDown={(event) => event.stopPropagation()} />}
          </div>
          <Button aria-label="companyName" data-testid="link-logo" href={innerUrls.main} link>
            <Image alt="companyName" className={cs.logo} height={44} priority src={LogoXL} width={171} />
          </Button>
          <Nav />

          <Avatar />
          {children}
        </div>
      </header>
    </>
  );
};
